import { BaseInjectHandler } from "../BaseInjectHandler";
import { EMessageC2C } from "../../../common/EMessageC2C";
import { HandleQueryObjList } from "./HandleQueryObjList";
import { TransPack } from "../../../server/framework/common/TransPack";
import { UInt8ArrayEx } from "../../../LTGame/Utils/UInt8ArrayEx";
import { Base64Ex } from "../../../LTGame/Utils/Base64Ex";

export class HandleQuerySceneImg extends BaseInjectHandler {

    msgId: number = EMessageC2C.QuerySceneImg;

    private _listHandle: HandleQueryObjList;
    private _lastScene: Laya.Scene3D;
    private _workCamera: Laya.Camera;
    private _cacheRt: Laya.RenderTexture;
    private _cacheSp: Laya.Sprite;
    private _isFirstQuery: boolean;

    private _cacheBinaryArray1: Uint8Array;
    private _cacheBinaryArray2: Uint8Array;
    private _stepIndex: number;

    public get workCamera(): Laya.Camera {
        return this._workCamera;
    }

    public isAbleToRender: boolean;

    _OnInit() {
        this._isFirstQuery = false;
        this._listHandle = this.owner.GetHandleById(EMessageC2C.QueryObjList) as HandleQueryObjList;
        this.isAbleToRender = false;

        this._InitCamera();
    }

    private _InitCamera() {
        this._workCamera = new Laya.Camera();
        this._workCamera.name = '__debugCamera';
        this._workCamera.enableRender = false;
        this._stepIndex = 0;
    }

    _OnHandleMsg(msg: TransPack) {
        let getId = msg.data.id;
        let width = msg.data.width;
        let height = msg.data.height;
        let isForce = msg.data.isForce as boolean;
        if (this._cacheRt == null) {
            this._cacheRt = new Laya.RenderTexture(width, height, Laya.RenderTextureFormat.R8G8B8A8);
            this._workCamera.renderTarget = this._cacheRt;
            this._cacheSp = new Laya.Sprite;
            this._cacheSp.texture = new Laya.Texture(this._cacheRt as any);

            this._cacheBinaryArray1 = new Uint8Array(width * height * 4);
            this._cacheBinaryArray2 = new Uint8Array(width * height * 4);

        } else if (this._cacheRt.width != width || this._cacheRt != height) {
            this._cacheRt.destroy();
            this._cacheRt = new Laya.RenderTexture(width, height, Laya.RenderTextureFormat.R8G8B8A8);
            this._workCamera.renderTarget = this._cacheRt;
            this._cacheSp.destroy();
            this._cacheSp = new Laya.Sprite;
            this._cacheSp.texture = new Laya.Texture(this._cacheRt as any);

            this._cacheBinaryArray1 = new Uint8Array(width * height * 4);
            this._cacheBinaryArray2 = new Uint8Array(width * height * 4);
        }

        let backData = new QueryImgBack();
        let getNode = this._listHandle.GetNodeById(getId);

        if (getNode == null || getNode.destroyed) {
            backData.code = -1;
            this.owner.SendTransOtherData(EMessageC2C.QuerySceneImg_Back, backData);
            this.isAbleToRender = false;
            return;
        }

        let searchScene: Laya.Scene3D = null;
        if (getNode instanceof Laya.Scene3D) {
            searchScene = getNode;
        }
        else if (getNode instanceof Laya.Sprite3D) {
            let sp3d = getNode as Laya.Sprite3D;
            searchScene = sp3d.scene;
        }

        if (searchScene != null && searchScene != this._lastScene) {
            this._lastScene = searchScene;
        }

        if (this._lastScene != null) {
            if (this._isFirstQuery) {
                this._isFirstQuery = false;
            }
            this._lastScene.addChild(this._workCamera);
            this._workCamera.render();
            this._workCamera.removeSelf();
            this._stepIndex++;
            let useArray = this._stepIndex % 2 == 1 ? this._cacheBinaryArray1 : this._cacheBinaryArray2;
            let backArray = this._stepIndex % 2 == 0 ? this._cacheBinaryArray1 : this._cacheBinaryArray2;
            this._cacheRt.getData(0, 0, this._cacheRt.width, this._cacheRt.height, useArray);

            if (useArray == backArray && !isForce) {
                backData.code = 1;
                backData.binImg = null;
            } else {
                backData.code = 0;
                backData.binImg = useArray;
            }
            this.isAbleToRender = true;
        } else {
            this.isAbleToRender = false;
            backData.code = -1;
        }
        this.owner.SendTransOtherData(EMessageC2C.QuerySceneImg_Back, backData);

    }

    public SearchCamera(): Laya.Camera {
        return this._DeepSearchCamera(this._lastScene);
    }

    private _DeepSearchCamera(node: Laya.Node): Laya.Camera {
        if (node == null) return null;
        if (node instanceof Laya.Camera) {
            return node;
        }
        for (let i = 0; i < node.numChildren; ++i) {
            let getChild = node.getChildAt(i);
            let result = this._DeepSearchCamera(getChild);
            if (result) {
                return result;
            }
        }
    }

}

export class QueryImgBack {

    public code: number;
    public binImg: Uint8Array;

}